<template>
  <view class="tabs" :class="tabsClass" :style="tabsStyle">
    <!-- 标签栏 -->
    <view class="tabs__nav" :class="navClass" :style="navStyle">
      <!-- 滚动容器 -->
      <scroll-view
        class="tabs__scroll"
        :scroll-x="scrollable"
        :scroll-left="scrollLeft"
        :scroll-with-animation="true"
        @scroll="handleScroll"
      >
        <!-- 标签列表 -->
        <view class="tabs__list" :style="listStyle">
          <view
            v-for="(tab, index) in tabs"
            :key="getTabKey(tab, index)"
            class="tabs__tab"
            :class="getTabClass(tab, index)"
            :style="getTabStyle(tab, index)"
            @click="handleTabClick(tab, index)"
          >
            <!-- 标签图标 -->
            <view v-if="tab.icon" class="tab__icon">
              <text class="icon">{{ tab.icon }}</text>
            </view>

            <!-- 标签文本 -->
            <text class="tab__text">{{ tab.label || tab.title }}</text>

            <!-- 徽章 -->
            <Badge
              v-if="tab.badge"
              :text="tab.badge.text"
              :type="tab.badge.type"
              :custom-class="tab.badge.customClass"
            />

            <!-- 关闭按钮 -->
            <view
              v-if="closable && tab.closable !== false && tabs.length > 1"
              class="tab__close"
              @click.stop="handleTabClose(tab, index)"
            >
              <text class="close-icon">✕</text>
            </view>
          </view>
        </view>

        <!-- 下划线指示器 -->
        <view
          v-if="type === 'line'"
          class="tabs__ink"
          :style="inkStyle"
        ></view>
      </scroll-view>

      <!-- 操作按钮 -->
      <view v-if="showActions" class="tabs__actions">
        <view
          v-if="showAddButton"
          class="action-btn"
          @click="handleAdd"
        >
          <text class="action-icon">+</text>
        </view>

        <view
          v-if="showMoreButton"
          class="action-btn"
          @click="handleMore"
        >
          <text class="action-icon">⋯</text>
        </view>
      </view>
    </view>

    <!-- 标签内容 -->
    <view class="tabs__content" :style="contentStyle">
      <swiper
        class="tabs__swiper"
        :current="currentIndex"
        :duration="swipeDuration"
        :circular="circular"
        @change="handleSwiperChange"
      >
        <swiper-item
          v-for="(tab, index) in tabs"
          :key="`content-${getTabKey(tab, index)}`"
          class="tabs__pane"
        >
          <view class="pane__content">
            <slot :name="`pane-${index}`" :tab="tab" :index="index">
              <!-- 默认渲染 tab.content -->
              <view v-if="tab.content" v-html="tab.content"></view>
              <!-- 或者使用 slot 的默认内容 -->
              <slot v-else name="default" :tab="tab" :index="index"></slot>
            </slot>
          </view>
        </swiper-item>
      </swiper>
    </view>

    <!-- 加载状态 -->
    <view v-if="loading" class="tabs__loading">
      <view class="loading-spinner"></view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, nextTick } from 'vue'
import Badge from './Badge.vue'

// 标签项接口
interface TabItem {
  key?: string | number
  label?: string
  title?: string
  icon?: string
  content?: string
  badge?: {
    text?: string
    type?: 'primary' | 'success' | 'warning' | 'danger' | 'info'
    customClass?: string
  }
  closable?: boolean
  disabled?: boolean
  [key: string]: any
}

// Props
interface Props {
  tabs?: TabItem[]
  modelValue?: string | number
  type?: 'line' | 'card' | 'segment'
  size?: 'small' | 'medium' | 'large'
  placement?: 'top' | 'bottom' | 'left' | 'right'
  scrollable?: boolean
  closable?: boolean
  showActions?: boolean
  showAddButton?: boolean
  showMoreButton?: boolean
  animated?: boolean
  swipeDuration?: number
  circular?: boolean
  tabBarGutter?: number
  inkBarWidth?: string
  inkBarHeight?: string
  inkBarColor?: string
  backgroundColor?: string
  activeColor?: string
  inactiveColor?: string
  customClass?: string
}

const props = withDefaults(defineProps<Props>(), {
  tabs: () => [],
  type: 'line',
  size: 'medium',
  placement: 'top',
  scrollable: false,
  closable: false,
  showActions: false,
  showAddButton: false,
  showMoreButton: false,
  animated: true,
  swipeDuration: 300,
  circular: false,
  tabBarGutter: 0,
  inkBarWidth: 'auto',
  inkBarHeight: '2px',
  inkBarColor: '#1890ff',
  backgroundColor: '#ffffff',
  activeColor: '#1890ff',
  inactiveColor: '#666666',
  customClass: ''
})

// Emits
const emit = defineEmits<{
  'update:modelValue': [value: string | number]
  change: [tab: TabItem, index: number]
  tabClick: [tab: TabItem, index: number]
  tabClose: [tab: TabItem, index: number]
  add: []
  more: []
}>()

// 响应式数据
const scrollLeft = ref(0)
const currentIndex = ref(0)
const tabWidths = ref<number[]>([])
const inkLeft = ref(0)
const inkWidth = ref(0)

// 计算属性
const tabsClass = computed(() => {
  return [
    `tabs--${props.type}`,
    `tabs--${props.size}`,
    `tabs--${props.placement}`,
    {
      'tabs--scrollable': props.scrollable,
      'tabs--animated': props.animated
    },
    props.customClass
  ]
})

const tabsStyle = computed(() => {
  return {
    backgroundColor: props.backgroundColor
  }
})

const navClass = computed(() => {
  return [
    {
      'tabs__nav--with-actions': props.showActions
    }
  ]
})

const navStyle = computed(() => {
  return {
    backgroundColor: props.type === 'card' ? '#f5f5f5' : props.backgroundColor
  }
})

const listStyle = computed(() => {
  const style: any = {}

  if (props.tabBarGutter > 0) {
    style.gap = `${props.tabBarGutter}px`
  }

  return style
})

const inkStyle = computed(() => {
  return {
    left: `${inkLeft.value}px`,
    width: props.inkBarWidth === 'auto' ? `${inkWidth.value}px` : props.inkBarWidth,
    height: props.inkBarHeight,
    backgroundColor: props.inkBarColor
  }
})

const contentStyle = computed(() => {
  return {
    backgroundColor: props.backgroundColor
  }
})

// 监听器
watch(() => props.modelValue, (newVal) => {
  const index = props.tabs.findIndex(tab => tab.key === newVal)
  if (index !== -1 && index !== currentIndex.value) {
    currentIndex.value = index
    updateInkBar()
  }
}, { immediate: true })

watch(currentIndex, (newVal) => {
  const tab = props.tabs[newVal]
  if (tab && tab.key !== props.modelValue) {
    emit('update:modelValue', tab.key)
    emit('change', tab, newVal)
  }
  scrollToTab(newVal)
})

// 生命周期
onMounted(() => {
  nextTick(() => {
    updateInkBar()
  })
})

// 方法
/**
 * 获取标签唯一键
 */
const getTabKey = (tab: TabItem, index: number) => {
  return tab.key || index
}

/**
 * 获取标签样式类
 */
const getTabClass = (tab: TabItem, index: number) => {
  return [
    'tab',
    {
      'tab--active': index === currentIndex.value,
      'tab--disabled': tab.disabled
    },
    tab.customClass
  ]
}

/**
 * 获取标签样式
 */
const getTabStyle = (tab: TabItem, index: number) => {
  const style: any = {}

  if (index === currentIndex.value) {
    style.color = props.activeColor
  } else {
    style.color = props.inactiveColor
  }

  return style
}

/**
 * 处理标签点击
 */
const handleTabClick = (tab: TabItem, index: number) => {
  if (tab.disabled) return

  currentIndex.value = index
  emit('tabClick', tab, index)
}

/**
 * 处理标签关闭
 */
const handleTabClose = (tab: TabItem, index: number) => {
  emit('tabClose', tab, index)
}

/**
 * 处理添加标签
 */
const handleAdd = () => {
  emit('add')
}

/**
 * 处理更多操作
 */
const handleMore = () => {
  emit('more')
}

/**
 * 处理滑动切换
 */
const handleSwiperChange = (e: any) => {
  currentIndex.value = e.detail.current
}

/**
 * 处理滚动
 */
const handleScroll = (e: any) => {
  // 可以在这里处理滚动逻辑
}

/**
 * 更新下划线位置
 */
const updateInkBar = () => {
  // 这里需要根据实际的标签宽度来计算
  // 在真实项目中，可能需要使用 uni.createSelectorQuery 来获取实际宽度
  if (props.type === 'line' && currentIndex.value >= 0) {
    // 简化的计算，实际应该获取标签元素的实际宽度
    const tabWidth = 100 // 临时值，应该动态计算
    inkLeft.value = currentIndex.value * tabWidth
    inkWidth.value = tabWidth
  }
}

/**
 * 滚动到指定标签
 */
const scrollToTab = (index: number) => {
  if (!props.scrollable) return

  // 这里应该根据实际的标签位置来计算滚动距离
  // 在真实项目中，可能需要使用 uni.createSelectorQuery 来获取实际位置
  const tabLeft = index * 100 // 临时值，应该动态计算
  scrollLeft.value = tabLeft
}

// 暴露方法给父组件
defineExpose({
  updateInkBar,
  scrollToTab
})
</script>

<style lang="scss" scoped>
.tabs {
  display: flex;
  flex-direction: column;
  width: 100%;
  position: relative;

  &--top {
    flex-direction: column;
  }

  &--bottom {
    flex-direction: column-reverse;
  }

  &--left {
    flex-direction: row;
  }

  &--right {
    flex-direction: row-reverse;
  }

  &__nav {
    display: flex;
    align-items: center;
    position: relative;
    background: #ffffff;
    z-index: 10;

    &--with-actions {
      padding-right: 40px;
    }
  }

  &__scroll {
    flex: 1;
    height: 100%;
  }

  &__list {
    display: flex;
    align-items: center;
    height: 100%;
    white-space: nowrap;
  }

  &__tab {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 16px;
    height: 44px;
    font-size: 14px;
    font-weight: 500;
    color: #666;
    cursor: pointer;
    transition: all 0.3s ease;
    position: relative;
    white-space: nowrap;

    &:active {
      opacity: 0.7;
    }

    &--active {
      color: #1890ff;
      font-weight: 600;
    }

    &--disabled {
      color: #ccc;
      cursor: not-allowed;
      pointer-events: none;
    }

    .tab__icon {
      margin-right: 6px;

      .icon {
        font-size: 16px;
      }
    }

    .tab__text {
      line-height: 1;
    }

    .tab__close {
      margin-left: 8px;
      padding: 2px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: background-color 0.2s ease;

      &:active {
        background: rgba(0, 0, 0, 0.1);
      }

      .close-icon {
        font-size: 12px;
        color: #999;
      }
    }
  }

  &__ink {
    position: absolute;
    bottom: 0;
    height: 2px;
    background: #1890ff;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    border-radius: 1px;
  }

  &__actions {
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    background: linear-gradient(90deg, transparent, #ffffff 80%);

    .action-btn {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 32px;
      height: 32px;
      margin: 0 4px;
      border-radius: 4px;
      cursor: pointer;
      transition: background-color 0.2s ease;

      &:active {
        background: #f0f0f0;
      }

      .action-icon {
        font-size: 16px;
        color: #666;
      }
    }
  }

  &__content {
    flex: 1;
    position: relative;
    overflow: hidden;
  }

  &__swiper {
    width: 100%;
    height: 100%;
  }

  &__pane {
    width: 100%;
    height: 100%;
    overflow-y: auto;
  }

  &__loading {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(255, 255, 255, 0.8);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 100;

    .loading-spinner {
      width: 24px;
      height: 24px;
      border: 2px solid #f3f3f3;
      border-top: 2px solid #1890ff;
      border-radius: 50%;
      animation: spin 1s linear infinite;
    }
  }

  // 类型样式
  &--line {
    .tabs__nav {
      border-bottom: 1px solid #f0f0f0;
    }
  }

  &--card {
    .tabs__nav {
      padding: 4px;
      background: #f5f5f5;
      border-radius: 8px;
      margin: 8px;
    }

    .tabs__tab {
      border-radius: 6px;
      height: 36px;
      background: transparent;

      &--active {
        background: #ffffff;
        box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
      }
    }

    .tabs__ink {
      display: none;
    }
  }

  &--segment {
    .tabs__nav {
      padding: 2px;
      background: #f0f0f0;
      border-radius: 20px;
      margin: 8px;
    }

    .tabs__tab {
      border-radius: 18px;
      height: 32px;
      background: transparent;
      font-size: 13px;

      &--active {
        background: #1890ff;
        color: #ffffff;
      }
    }

    .tabs__ink {
      display: none;
    }
  }

  // 尺寸样式
  &--small {
    .tabs__tab {
      height: 36px;
      padding: 0 12px;
      font-size: 13px;
    }
  }

  &--medium {
    .tabs__tab {
      height: 44px;
      padding: 0 16px;
      font-size: 14px;
    }
  }

  &--large {
    .tabs__tab {
      height: 52px;
      padding: 0 20px;
      font-size: 16px;
    }
  }

  // 动画样式
  &--animated {
    .tabs__pane {
      transition: transform 0.3s ease;
    }
  }
}

.pane__content {
  width: 100%;
  height: 100%;
  padding: 16px;
  box-sizing: border-box;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

// 响应式设计
@media (max-width: 480px) {
  .tabs {
    &__tab {
      padding: 0 12px;
      font-size: 13px;
    }

    &--large &__tab {
      padding: 0 16px;
      font-size: 15px;
    }
  }
}
</style>